﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.DataModel;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayFireExtinguisher : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIApplication application = commandData.Application;
			UIDocument activeUIDocument = application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			if (commandData == null)
			{
				throw new System.ArgumentNullException();
			}
			List<ViewType> list = new List<ViewType>();
            list.Add((ViewType)1);
            list.Add((ViewType)2);
            list.Add((ViewType)4);
			if (!YJKRevitTools.ViewCheck(application.ActiveUIDocument, list))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Transaction transaction = null;
			Result result;
			try
			{
				HYEquipmentCommon hyequipmentCommon = new HYEquipmentCommon();
				SpaceFamilyDataReader spaceFamilyDataReader = new SpaceFamilyDataReader();
				FormLayFireExtinguisher formLayFireExtinguisher = new FormLayFireExtinguisher(document);
				if (formLayFireExtinguisher.ShowDialog() == DialogResult.OK)
				{
					FireExtinguisherParam fireExtinguisherParam = formLayFireExtinguisher.fireExtinguisherParam;
					FamilySymbol familySymbolById = spaceFamilyDataReader.GetFamilySymbolById(fireExtinguisherParam.Id, "FireExtinguisher", document, BuiltInCategory.OST_MechanicalEquipment);
					if (familySymbolById != null)
					{
						ConnectHelper connectHelper = new ConnectHelper();
						double num = familySymbolById.GetParameter("模型线实际长度1").AsDouble();
						if (familySymbolById.GetFamilyNameBySymbol().Contains("推车"))
						{
							num = 0.95144356955380571;
						}
						else
						{
							num = 0.9120734908136483;
						}
						double num2 = num * fireExtinguisherParam.Scale;
						for (;;)
						{
							transaction = new Transaction(document, "布置灭火器");
							transaction.Start();
							ICollection<ElementId> allFamilyInstance = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
							double num3 = 0.0;
							double num4 = 0.0;
							ConnectHelper.GetTagTextWidthAndHeight(fireExtinguisherParam.Mode, document, ref num3, ref num4);
							double num5 = num4 / 304.8 + num;
							if (formLayFireExtinguisher.layTerminalType == 1)
							{
								List<XYZ> list2 = new List<XYZ>();
								XYZ xyz = selection.PickPoint("选择一个点坐标，以这个点坐标为中心，布置单个或多个灭火器");
								num5 = this.GetMarkMoveDistance(num5, document, 0);
								XYZ origin = new XYZ(xyz.X, xyz.Y + num5, xyz.Z);
								int count = fireExtinguisherParam.Count;
								if (count > 2 && count % 2 != 0)
								{
									list2.Add(xyz);
									for (int i = 1; i <= (count - 1) / 2; i++)
									{
										list2.Add(new XYZ(xyz.X + (double)i * num2, xyz.Y, xyz.Z));
										list2.Add(new XYZ(xyz.X - (double)i * num2, xyz.Y, xyz.Z));
									}
								}
								else if (count > 1 && count % 2 == 0)
								{
									for (int j = 1; j <= count / 2; j++)
									{
										list2.Add(new XYZ(xyz.X + ((double)j - 0.5) * num2, xyz.Y, xyz.Z));
										list2.Add(new XYZ(xyz.X - ((double)j - 0.5) * num2, xyz.Y, xyz.Z));
									}
								}
								else if (count == 1)
								{
									list2.Add(xyz);
								}
								if (list2 != null && list2.Count > 0)
								{
									connectHelper.LayFamilyInstance(list2, familySymbolById, document.ActiveView.GenLevel, 0, document);
									if (fireExtinguisherParam.IsLable)
									{
										document.GetTextNode(document.ActiveView, origin, new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), (double)StringTools.GetStringByteLength(fireExtinguisherParam.Mode) / 100.0, (Autodesk.Revit.DB.TextAlignFlags)128, fireExtinguisherParam.Mode).TextNoteType.GetParameter(BuiltInParameter.TEXT_BACKGROUND).Set(1);
									}
								}
							}
							else if (formLayFireExtinguisher.layTerminalType == 0)
							{
								List<Element> list3 = new List<Element>();
								ISelectionFilter selectionFilter = new EquipmentSelectionFilter();
								IList<Element> list4 = selection.PickElementsByRectangle(selectionFilter, "框选一个或多个消火栓");
								if (list4.Count > 0)
								{
									foreach (Element element in list4)
									{
										if ((element as FamilyInstance).Symbol.Family.Name.Contains("消火栓") || (element as FamilyInstance).Symbol.Family.Name.Contains("消防"))
										{
											list3.Add(element);
										}
									}
									if (list3.Count > 0)
									{
										List<string> list5 = new List<string>();
										foreach (Element element2 in list3)
										{
											List<XYZ> list6 = new List<XYZ>();
											XYZ point = (element2.Location as LocationPoint).Point;
											double num6;
											if (element2.GetParameter("宽度") == null)
											{
												FamilySymbol symbol = (element2 as FamilyInstance).Symbol;
												if (symbol.GetParameter("宽度") == null)
												{
													if (!list5.Contains((element2 as FamilyInstance).Symbol.Family.Name))
													{
														list5.Add((element2 as FamilyInstance).Symbol.Family.Name);
														continue;
													}
													continue;
												}
												else
												{
													num6 = symbol.GetParameter("宽度").AsDouble();
												}
											}
											else
											{
												num6 = element2.GetParameter("宽度").AsDouble();
											}
											XYZ xyz2 = -(element2 as FamilyInstance).FacingOrientation;
											XYZ xyz3 = (element2 as FamilyInstance).FacingOrientation.CrossProduct(new XYZ(0.0, 0.0, -1.0));
											XYZ xyz4 = point + num6 * xyz2;
											double markMoveDistance = this.GetMarkMoveDistance(num5, document, 1);
											XYZ origin2 = xyz4 + markMoveDistance * xyz2;
											int count2 = fireExtinguisherParam.Count;
											if (count2 > 2 && count2 % 2 != 0)
											{
												list6.Add(xyz4);
												for (int k = 1; k <= (count2 - 1) / 2; k++)
												{
													list6.Add(xyz4 + (double)k * num2 * xyz3);
													list6.Add(xyz4 - (double)k * num2 * xyz3);
												}
											}
											else if (count2 > 1 && count2 % 2 == 0)
											{
												for (int l = 1; l <= count2 / 2; l++)
												{
													list6.Add(xyz4 + ((double)l - 0.5) * num2 * xyz3);
													list6.Add(xyz4 - ((double)l - 0.5) * num2 * xyz3);
												}
											}
											else if (count2 == 1)
											{
												list6.Add(xyz4);
											}
											if (list6 != null && list6.Count > 0)
											{
												ElementSet elementSet = connectHelper.LayFamilyInstance(list6, familySymbolById, document.ActiveView.GenLevel, 0, document);
												if (fireExtinguisherParam.IsLable)
												{
													document.GetTextNode(document.ActiveView, origin2, xyz3, xyz3.CrossProduct(new XYZ(0.0, 0.0, 1.0)), (double)StringTools.GetStringByteLength(fireExtinguisherParam.Mode) / 100.0, (Autodesk.Revit.DB.TextAlignFlags)128, fireExtinguisherParam.Mode).TextNoteType.GetParameter(BuiltInParameter.TEXT_BACKGROUND).Set(1);
												}
												document.Regenerate();
												XYZ xyz5 = (element2 as FamilyInstance).FacingOrientation * -1.0;
												foreach (object obj in elementSet)
												{
													Element element3 = (Element)obj;
													XYZ point2 = (element3.Location as LocationPoint).Point;
													Line line = Line.CreateBound(point2, point2.Add(new XYZ(0.0, 0.0, 1.0)));
													XYZ facingOrientation = (element3 as FamilyInstance).FacingOrientation;
													double num7 = YJKRevitTools.GetTwoVectorAngle(xyz5, facingOrientation, new XYZ(0.0, 0.0, 1.0));
													if (num7 > 0.017453292519943295)
													{
														ElementTransformUtils.RotateElement(document, element3.Id, line, num7);
													}
													if (!facingOrientation.IsAlmostEqualTo(xyz5, 0.0001))
													{
														num7 = Math.PI*2 - 2.0 * num7;
														ElementTransformUtils.RotateElement(document, element3.Id, line, num7);
													}
												}
											}
										}
										if (list5.Count > 0)
										{
											string text = "有下列不是盈建科标准的消火栓，故不能布置灭火器：\n";
											for (int m = 0; m < list5.Count; m++)
											{
												if (m >= 5)
												{
													text += "\n......";
													break;
												}
												text = text + "\n" + list5[m];
											}
											MessageBox.Show(text, "盈建科提示");
										}
									}
								}
							}
							ICollection<ElementId> allFamilyInstance2 = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
							new List<ElementId>();
							foreach (ElementId item in allFamilyInstance.Intersect(allFamilyInstance2))
							{
								allFamilyInstance2.Remove(item);
							}
							new AuxiliaryLineOperate();
							foreach (ElementId elementId in allFamilyInstance2)
							{
								Element elementById = document.GetElementById(elementId);
								if (fireExtinguisherParam.Mode != "")
								{
									this.SetParameterValue(elementById, "灭火器型号", fireExtinguisherParam.Mode);
								}
								if (fireExtinguisherParam.JiBie != "")
								{
									this.SetParameterValue(elementById, "灭火级别", fireExtinguisherParam.JiBie);
								}
								if (fireExtinguisherParam.Agent != "")
								{
									this.SetParameterValue(elementById, "灭火剂", fireExtinguisherParam.Agent);
								}
								if (fireExtinguisherParam.SymbolName != "")
								{
									this.SetParameterValue(elementById, "灭火器类型", fireExtinguisherParam.SymbolName);
								}
								if (fireExtinguisherParam.Scale != 0.0)
								{
									this.SetParameterValue(elementById, "缩放比例", fireExtinguisherParam.Scale);
								}
								HYParametersSetting hyparametersSetting = new HYParametersSetting(application);
								Parameter parameter = elementById.GetParameter("保护半径");
								if (parameter == null)
								{
									hyparametersSetting.SetFireExtinguisherRudioShareParam();
									parameter = elementById.GetParameter("保护半径");
								}
								if (parameter != null)
								{
									parameter.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.Radius * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
								}
								Parameter parameter2 = null;
								Parameter parameter3 = null;
								double num8 = 0.0;
								if (elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM) != null)
								{
									parameter3 = elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
								}
								else
								{
									Parameter parameter4 = elementById.GetParameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
									if (parameter4 != null)
									{
										parameter4.Set(document.ActiveView.GenLevel.Id);
									}
								}
								if (parameter3 != null)
								{
									parameter3.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
									num8 = parameter3.AsDouble();
								}
								if (num8 != UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2))
								{
									if (elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM) != null)
									{
										parameter2 = elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
									}
									if (parameter2 != null)
									{
										parameter2.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
									}
								}
								CreateProtectRange createProtectRange = new CreateProtectRange();
								if (fireExtinguisherParam.Range && (int)document.ActiveView.ViewType != 4)
								{
									document.Regenerate();
									List<Element> collection = new List<Element>
									{
										elementById
									};
									createProtectRange.CreatActiveViewDetailCurve(document, collection, this.hyGPS);
								}
							}
							document.Regenerate();
							transaction.Commit();
						}
					}
				}
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null && (int)transaction.GetStatus() != 3)
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private void SetParameterValue(Element elem, string paramName, string paramValue)
		{
			Parameter parameter = elem.GetParameter(paramName);
			if (parameter != null && !parameter.IsReadOnly && (int)parameter.StorageType == 3)
			{
				parameter.Set(paramValue);
			}
		}

		private void SetParameterValue(Element elem, string paramName, double paramValue)
		{
			Parameter parameter = elem.GetParameter(paramName);
			if (parameter != null && !parameter.IsReadOnly && (int)parameter.StorageType == 2)
			{
				parameter.Set(paramValue);
			}
		}

		private int GetElemTagElementId(Autodesk.Revit.DB.Document doc)
		{
			string markFamilyPath = UnifiedModified.GetMarkFamilyPath(doc, "灭火器标注族");
			int num = 0;
			try
			{
				foreach (Element element in YJKElementFilter.GetElementsOfType(doc, typeof(FamilySymbol), BuiltInCategory.OST_FireAlarmDeviceTags))
				{
					if (element.Name == "灭火器标注族")
					{
						num = element.Id.IntegerValue;
					}
				}
				if (num == 0)
				{
					doc.LoadFamily(markFamilyPath);
					foreach (Element element2 in YJKElementFilter.GetElementsOfType(doc, typeof(FamilySymbol), BuiltInCategory.OST_FireAlarmDeviceTags))
					{
						if (element2.Name == "灭火器标注族")
						{
							num = element2.Id.IntegerValue;
						}
					}
				}
			}
			catch (Exception)
			{
				throw;
			}
			return num;
		}

		private double GetMarkMoveDistance(double moveDistance, Autodesk.Revit.DB.Document doc, int markStyle)
		{
			if (markStyle == 0)
			{
				string version = RevitVersion.Version;
				if (!(version == "2017"))
				{
					if (version == "2016")
					{
						moveDistance -= 0.41010498687664043 * (double)doc.ActiveView.Scale / 100.0;
					}
				}
				else
				{
					moveDistance -= 0.5741469816272966 * (double)doc.ActiveView.Scale / 100.0;
				}
			}
			if (markStyle == 1)
			{
				string version = RevitVersion.Version;
				if (!(version == "2017"))
				{
					if (version == "2016")
					{
						moveDistance -= 0.32808398950131235 * (double)doc.ActiveView.Scale / 100.0;
					}
				}
				else
				{
					moveDistance -= 0.50853018372703407 * (double)doc.ActiveView.Scale / 100.0;
				}
			}
			return moveDistance;
		}

		private HyRangeCheckMajor hyGPS;
	}
}
